# function: print "Hello World!"
# copyright: 从零开始编写linux内核
# 1. 定义常量BOOTSEG， 早期8086的寄存器为16位，为了寻址20位地址线，采用了两个寄存器拼接的方式来计算地址
# 2. 即add=base(r1<<4) + offset(r2),这里0x7C0 << 4 = 0x7c00为BIOS的标准加载地址
BOOTSEG = 0x7c0

.code16  # 告诉汇编器生成16位代码
.text    # 标识接下来的代码是文本段

.global _start  # 声明_start为全局符号，便于链接器寻找
_start:
    jmpl $BOOTSEG, $start2  # 将代码段寄存器（CS）设置为 BOOTSEG，并跳转到 start2 标签

start2:
    # 将 BOOTSEG 的值加载到 AX 寄存器，然后将 AX 的值分别移动到 DS、ES、FS 和 GS 寄存器中。这是为了确保数据段寄存器正确设置，以便后续的数据访问操作
    movw $BOOTSEG, %ax
    movw %ax, %ds
    movw %ax, %es 
    movw %ax, %fs 
    movw %ax, %gs

    movw $msg, %ax      # 将字符串地址加载到ax寄存器
    movw %ax, %bp       # 将ax的值移动到bp寄存器，bp通常用于基址寻址
    movw $0x01301, %ax  # 设置ax寄存器为0x01301，控制显示方式
    movw $0x0c, %bx     # 文字为红色
    movw $12, %cx       # 字符串长度
    movb $0, %dl        # 设置 DL 寄存器为 0，表示输出光标的位置，dh表示行号，dl表示列号
    int $0x010          # 调用 BIOS 中断 0x10，这是一个视频服务中断，用于显示字符串

# 创建一个无限循环
loop:
    jmp loop

msg:
.ascii "Hello World!"

.org 510  # 将接下来的数据放在偏移量 510 的位置
boot_flag:  # 定义了一个引导标志 0xaa55，这是 BIOS 用来识别有效引导扇区的标志
    .word 0xaa55

# 编译命令:
# as bootsect.S -o bootsect.o
# ld -m elf_x86_64 -Ttext 0x0 -s --oformat binary -o linux.img bootsect.o
# 运行命令:
# qemu-system-x86_64  -boot a -fda linux.img 
# qemu-system-x86_64 -boot a -fda linux.img 是一个用于启动 QEMU 模拟器的命令行选项，具体含义如下：
# -boot a：这个选项指定了启动顺序。a 表示从软盘（floppy disk）启动。QEMU 会尝试从软盘启动虚拟机。
# -fda linux.img：这个选项指定了软盘 A 驱动器（floppy drive A）的镜像文件。linux.img 是一个软盘镜像文件，QEMU 会将其挂载到虚拟机的软盘 A 驱动器上。
